<template>
	<uni-popup ref="popupRef" type="bottom" @change="popupChange">
		<view class="bg-white">
			<PickerTitle @cancel="close" @ok="ok" :title="innerTitle" />
			<picker-view
				style="width:750rpx;"
				:style="{ height: pickerHeight + 'px' }"
				:indicator-style="'height:' + pickerHeight / 5 + 'px'"
				:value="pickerValue"
				@change="pickerChange"
			>
				<picker-view-column>
					<view class="date-picker-item" v-for="(item, index) in yearData" :key="item.value">
						<text class="text-m" :class="[pickerValue[0] === index ? 'color-active' : 'color-main']">
							{{ item.text }}
						</text>
					</view>
				</picker-view-column>
				<picker-view-column v-if="mode === 'm' || mode === 'd'">
					<view class="date-picker-item" v-for="(item, index) in monthData" :key="item.value">
						<text class="text-m" :class="[pickerValue[1] === index ? 'color-active' : 'color-main']">
							{{ item.text }}
						</text>
					</view>
				</picker-view-column>
				<picker-view-column v-if="mode === 'd'">
					<view class="date-picker-item" v-for="(item, index) in dayData" :key="item.value">
						<text class="text-m" :class="[pickerValue[2] === index ? 'color-active' : 'color-main']">
							{{ item.text }}
						</text>
					</view>
				</picker-view-column>
			</picker-view>
		</view>
	</uni-popup>
</template>

<script>
import { ref, watch, nextTick } from 'vue';
import { getRange, paddingZero } from '../../../utils/common.js';
import dateUtil from '../../../utils/date.js';
import Calendar from '../../lib/datetime-picker/calendar.js';
import PickerTitle from '../item-picker/picker-title.vue';

const modeSetting = {
	y: {
		title: '选择年份',
	},
	m: {
		title: '选择年月',
	},
	d: {
		title: '选择日期',
	},
};
export default {
	components: {
		PickerTitle,
	},
	props: {
		title: String,
		//y m d
		mode: {
			default: 'd',
			type: String,
		},
		maxDate: Object,
	},
	emits: ['pick'],
	setup(props, ctx) {
		const popupRef = ref();
		const pickerHeight = ref(uni.upx2px(550));
		const setting = modeSetting[props.mode];
		const innerTitle = ref(props.title || setting.title);
		//索引
		const pickerValue = ref([]);
		function popupChange(e) {}
		function pickerChange(e) {
			valueChange(e.detail.value);
		}
		function valueChange(newValue) {
			pickerValue.value = newValue;
			if (props.mode === 'd') {
				const valObj = indexToValue(pickerValue.value);
				const newMonthData = getMonthData(valObj.year);
				if (newMonthData.length !== monthData.value.length) {
					//长度不同 数据要更新
					monthData.value = newMonthData;
					const index = newMonthData.findIndex((el) => el.value === valObj.month);
					if (index === -1) {
						//month value需更新
						const newValue = [...pickerValue.value];
						newValue[1] = newMonthData.length - 1;
						pickerValue.value = newValue;
					}
				}
				const newDayData = getDayData(valObj.year, valObj.month);
				if (newDayData.length !== dayData.value.length) {
					//长度不同 数据要更新
					dayData.value = newDayData;
					const index = newDayData.findIndex((el) => el.value === valObj.day);
					if (index === -1) {
						//day value需更新
						const newValue = [...pickerValue.value];
						newValue[2] = newDayData.length - 1;
						pickerValue.value = newValue;
					}
				}
			}
		}
		function open(options = {}) {
			if (options.value) {
				let value = options.value;
				if (typeof value == 'object') {
					value = dateUtil.format(value);
				}
				//xxxx-xx-xx value要转化为索引
				const vals = value.split('-');
				const indexVals = [];
				const yIndex = yearData.findIndex((el) => el.value === parseInt(vals[0]));
				indexVals.push(yIndex);
				if (vals[1]) {
					const mIndex = monthData.value.findIndex((el) => el.value === parseInt(vals[1]));
					indexVals.push(mIndex);
				}
				if (vals[2]) {
					const dIndex = dayData.value.findIndex((el) => el.value === parseInt(vals[2]));
					indexVals.push(dIndex);
				}
				valueChange(indexVals);
			}
			popupRef.value.open();
		}
		function close() {
			popupRef.value.close();
		}
		function ok() {
			const valObj = indexToValue(pickerValue.value);
			const result = [];
			['year', 'month', 'day'].forEach((key) => {
				if (valObj[key] !== null) {
					result.push(paddingZero(valObj[key]));
				}
			});
			ctx.emit('pick', {
				value: result.join('-'),
				item: valObj,
			});
			close();
		}
		const yearData = getRange(1970, props.maxDate ? props.maxDate.getFullYear() : 2100, {
			formatter(v) {
				return { text: v + '年', value: v };
			},
		});
		const monthData = ref([]);
		const dayData = ref([]);
		function getDayData(y, m) {
			const maxDate = props.maxDate;
			const maxDay = (maxDate && maxDate.getFullYear() === y && maxDate.getMonth() + 1 === m) ? maxDate.getDate() : Calendar.solarDays(y, m);
			return getRange(1, maxDay, {
				formatter(v) {
					return { text: v + '日', value: v };
				},
			});
		}
		function getMonthData(y) {
			const maxDate = props.maxDate;
			const maxMonth = maxDate && maxDate.getFullYear() === y ? maxDate.getMonth() + 1 : 12;
			return getRange(1, maxMonth, {
				formatter(v) {
					return { text: v + '月', value: v };
				},
			});
		}
		function indexToValue(indexVal) {
			return {
				year: isValidIndex(indexVal[0], yearData) ? yearData[indexVal[0]].value : null,
				month: isValidIndex(indexVal[1], monthData.value) ? monthData.value[indexVal[1]].value : null,
				day: isValidIndex(indexVal[2], dayData.value) ? dayData.value[indexVal[2]].value : null,
			};
		}
		function isValidIndex(index, data) {
			return index !== undefined && data[index] !== undefined;
		}
		function setValueByDate(date) {
			const y = date.getFullYear();
			const m = date.getMonth() + 1;
			const d = date.getDate();
			const vals = [];
			const yIndex = yearData.findIndex((el) => el.value === y);
			vals.push(yIndex);
			if (props.mode === 'm') {
				monthData.value = getMonthData(y);
				const mIndex = monthData.value.findIndex((el) => el.value === m);
				vals.push(mIndex);
			}
			if (props.mode === 'd') {
				monthData.value = getMonthData(y);
				dayData.value = getDayData(y, m);
				const dIndex = dayData.value.findIndex((el) => el.value === d);
				vals.push(dIndex);
			}
			pickerValue.value = vals;
		}
		const now = new Date();
		setValueByDate(now);
		return {
			pickerHeight,
			popupChange,
			pickerChange,
			pickerValue,
			open,
			close,
			ok,
			innerTitle,
			yearData,
			monthData,
			dayData,
			popupRef,
		};
	},
};
</script>

<style>
.date-picker-item {
	font-size: 0;
	display: flex;
	align-items: center;
	justify-content: center;
}
</style>
